package de.fhffm.gui;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.tables.Aussaat;
import de.fhffm.tables.Wachstum;

public class WachstumFenster implements ActionListener {
	
	private String keimung = null;
	private String datum = null;
	private String groesseString = null;
	
	private Double groesse = 0.0;
	
	private JTextField txtKeimung = new JTextField(8);
	private JTextField txtGroesse = new JTextField(8);
	
	private JFormattedTextField txtDatum ;
	
	private JLabel lblKeimung = new JLabel("Keimung");
	private JLabel lblGroesse = new JLabel("Größe");
	private JLabel lblDatum = new JLabel("Datum");
	private JLabel infoLabel = new JLabel();
	

	private JButton btnSpeichern = new JButton("Speichern");
	private JButton btnAbbrechen = new JButton("Abbrechen");
	
	private JPanel eingabePanel = new JPanel(new GridLayout(3,2));
	private JPanel buttonPanel = new JPanel();
	private JPanel infoPanel = new JPanel();
	
	private JFrame wachstumFrame = new JFrame();
	
	private List<String> ausgewaehlteZeile;
	
	private StringBuilder sb = new StringBuilder();
	
	private MaskFormatter datumFormat= null;
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private Date aktuellesDatum = new Date();
	
	private Wachstum wachstum;
	
	private boolean wachstumVorhanden = false;
	
	private int wachstumID; 
	

	WachstumFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		
		wachstumFrame.setSize(400,500);
		wachstumFrame.setLocationRelativeTo(null);
		wachstumFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		wachstumFrame.setVisible(true);
		wachstumFrame.setResizable(true);
		wachstumFrame.setLayout(new BorderLayout());
		
		wachstumFrame.setTitle("Wachstum festlegen");
		sb.append("<html>Wachstum für die Aussaat mit der ID: ").append(ausgewaehlteZeile.get(0));
		sb.append("<br>").append(" vom ").append(ausgewaehlteZeile.get(1)).append(" festlegen.");
		sb.append("<br>Eingesetzte Pflanze: '").append(ausgewaehlteZeile.get(2)).append("'<br>");
		
		ueberpruefeWachstum();
		
		infoLabel.setText(sb.toString());
		sb.setLength(0);
		infoPanel.add(infoLabel);
		
		eingabePanel.add(lblKeimung);
		eingabePanel.add(txtKeimung);
		txtKeimung.setToolTipText("Aktuelle Keimung der Pflanze eintragen zB.: Sprössling");
		eingabePanel.add(lblGroesse);
		eingabePanel.add(txtGroesse);
		eingabePanel.add(lblDatum);
		setzeDatumTxtFeld();
		
		buttonPanel.add(btnSpeichern);
		btnSpeichern.addActionListener(this);
		buttonPanel.add(btnAbbrechen);
		btnAbbrechen.addActionListener(this);
		
		wachstumFrame.getContentPane().add(infoPanel, BorderLayout.NORTH);
		wachstumFrame.getContentPane().add(eingabePanel,BorderLayout.CENTER);
		wachstumFrame.getContentPane().add(buttonPanel,BorderLayout.SOUTH);
		wachstumFrame.pack();
		
	}

	private void ueberpruefeWachstum() {
		
		if(istWachstumVorhanden()){
			fuelleTextFelder();
		}else {
			System.out.println("Noch kein Wachstum vorhanden");
		}
	}


	private void fuelleTextFelder() {
		
		 sb.append("Für diese Aussaat gibt es ein vorheriges Wachstum vom ").append(wachstum.getWachstumDatum()).append("<br></html>");
		 txtKeimung.setText(wachstum.getKeimung());
		 groesseString = wachstum.getGroesse();
		 String[] teilString = groesseString.split(Pattern.quote(" ")); // cm entfernen
		 txtGroesse.setText(teilString[0]);

	}

	private boolean istWachstumVorhanden() {

		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("test");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	

		 Wachstum wachstum = aussaat.getWachstum();
	
		em.close(); 

		try{	
		 /*Wenn es keinen vorherigen Wachstum für die Aussaat gibt wird hier eine Exception geworfen
		  * wenn dies geschieht wird die Exception gefangen und man weiß das es noch keinen Wachstum gibt
		  */
		 wachstumID = wachstum.getWachstumID();
		}catch(NullPointerException e){
			wachstumVorhanden = false;
			return false;
		}
		
		 this.wachstum = wachstum;
		 wachstumVorhanden = true;
		return true;
	}


	private void setzeDatumTxtFeld() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		txtDatum = new JFormattedTextField(datumFormat);
		txtDatum.setText(simpleDateFormat.format(aktuellesDatum));
		eingabePanel.add(txtDatum);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource();

		if (obj == btnAbbrechen) {	
			wachstumFrame.dispose();
		}
		
		if(obj == btnSpeichern){
	
			/*
			 * Eingabe wird überprüft wenn alles OK ist
			 * dan wird überprüft ob das Wachstum neu hinzugefügt oder 
			 * geupdatet werden muss.
			 * Falls es geupdatet wird, wird nochmal überprüft ob das Update
			 * nicht evtl abgebrochen wurde, weil der nutzer darauf hingewiesen
			 * wurde das der vorherige Wachstum gelöscht wird und er das nicht möchte
			 */
			if(ueberpruefeEingabe()){
				
				if(wachstumVorhanden){
					
					if(doUpdateWachstum()){
						einfügenEnde();
				
					}else{
						//Update abebrochen -> nix passiert
					}
					
				}else{
					fuegeWachstumEin();
					einfügenEnde();
				}
				
					
			}else{
				System.out.println("Ein Fehler ist aufgetreten");
			}
		}
	}
		
	private boolean doUpdateWachstum() {
		
		Object[] options = {"Löschen","Abbrechen"};
		int selected = JOptionPane.showOptionDialog(null,"Das vorherige Wachstum wird überschrieben!", "ACHTUNG!", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		switch(selected){
		case 0:
		
			System.out.println("Der aktuelle Wachstum wird überschrieben");
			EntityManagerFactory factory;
			factory = Persistence.createEntityManagerFactory("test");
			EntityManager em = factory.createEntityManager();
			em.getTransaction().begin();
			
			Query q = em.createQuery("UPDATE Wachstum w SET w.keimung = :keimung , w.groesse = :groesse , w.datum =:datum WHERE w.wachstumID = :ID");
					  q.setParameter("keimung", keimung);
					  q.setParameter("groesse", groesseString);
					  q.setParameter("datum", datum);
					  q.setParameter("ID",wachstumID);
					  q.executeUpdate();
					  
			em.getTransaction().commit();
			em.close(); 
			return true;
			
		case 1:
			System.out.println("Update abgebrochen!");
			return false;
			
		}
		return false;
		
	}

	private void fuegeWachstumEin() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("test");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();		
		
		Wachstum wachstum = new Wachstum();
		
		wachstum.setAussaat(aussaat);
		wachstum.setKeimung(keimung);
		wachstum.setGroesse(groesseString);
		wachstum.setWachstumDatum(datum);
		
		em.persist(aussaat);
		em.persist(wachstum);
		em.flush();
		em.getTransaction().commit();
		em.refresh(wachstum);
		em.refresh(aussaat);
		em.close(); 
		
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();

		} catch (InputException e) {
			System.out.println("Eingabe Fehler");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für die Größe nur Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
		
	}

	private boolean hohleEingabe() throws InputException,NumberFormatException {
		
		keimung = txtKeimung.getText();
		groesse = Double.parseDouble(txtGroesse.getText());
		sb.append(groesse).append(" cm");
		groesseString = sb.toString();
		sb.setLength(0);
		
		if(isEingabeLeer()){
			
			throw new InputException("Eine oder mehrere Eingaben fehlen.");
			
		
		}else{

			return true;

		}
}

	private void ueberpruefeDatum() throws InputException {
	
		/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
		Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
		so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
		datum = txtDatum.getText();
		Date eingegebenesDatum = null;				
		String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
		String[] teilString = datum.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
	 
		try {
		
			eingegebenesDatum = simpleDateFormat.parse(datum);
			aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
		
		} catch (ParseException e) {
			e.printStackTrace();
		}
	
		if(eingegebenesDatum.after(aktuellesDatum)){
			throw new InputException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
		
			// Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
			// um dies zu überprüfen wird der vorher gesplittete String genutzt
		}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0")) ){
			throw new InputException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
	
		}else if(eingegebenesDatum.equals(aktuellesDatum)){
			System.out.println("Alles ok");
		}
	}

	private boolean isEingabeLeer() {
	
		if(keimung.length() == 0 || groesse == 0.0 ){
	
			return true;
	
		}else{
	
			return false;
		}
	}

	private void einfügenEnde() {
	
		Object[] options = {"Fertig!","Neuer Wachstum!"};
		int selected = JOptionPane.showOptionDialog(null,"Wachstum hinzugefügt!", "Hinzufügen Erfolgreich", JOptionPane.YES_NO_OPTION,
				   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
	
		switch(selected){
		case 0:
			wachstumFrame.dispose();
			break;
		case 1:
			wachstumFrame.dispose();
			new FortschrittTabellenFenster(1);
			break;
		}
	}
}
